//导入express框架
const express = require('express')
// 导入cors解决跨域问题
const cors = require('cors')
// 导入解析token字符串的expressjwt方法
const { expressjwt } = require('express-jwt')
const Joi = require('joi')
// 导入配置文件
const config = require('./config')
// 导入不需要公共路由对象
const publicRouter = require('./router/noTokenRouter')
// 导入普通用户路由
const userRouter = require('./router/user')
// 导入商家用户路由
const busRouter = require('./router/busRouter')

// 创建app实例
const app = express()

// 配置中间件再res身上挂载返回出错时的数据
app.use((req, res, next) => {
  // 挂载方法
  res.cc = (err, code = 1) => {
    // err:表示错误信息
    // code：表示错误的状态码
    res.send({
      msg: err instanceof Error ? err.message : err,
      code
    })
  }
  // 必须调用next方法，否则将无法往下执行
  next()
})

// 配置跨域
app.use(cors())

// 配置解析字符串的中间件,并且设置以api开头的路由不需要身份认证
app.use(expressjwt({ secret: config.secretKey, algorithms: ['HS256'] }).unless({ path: [/^\/api\//] }))

// 配置解析表单数据中间件, 注意，这个中间件需要在注册路由之前进行注册
app.use(express.urlencoded({ extended: false, limit: '2100000kb' }))
app.use(express.json({ limit: '2100000kb' }))

// 注册路由, 用户发起请求时需要在请求路径的前面添加/api前缀
app.use('/api', publicRouter)
// 注册普通用户路由，用户发起请求时需要在请求路径的前面添加/user前缀
app.use('/user', userRouter)
// 注册商家用户路由，用户发起请求时需要在请求路径的前面添加/bus前缀
app.use('/bus', busRouter)

// 注册静态资源目录
app.use('/api', express.static('./public'))

// 配置错误中间件
// 定义错误级别中间件
app.use((err, req, res, next) => {
  // 捕获表单验证错误
  if (err instanceof Joi.ValidationError) {
    return res.cc(err)
  }
  // 捕获token身份验证错误
  if (err.name === 'UnauthorizedError') {
    return res.cc('身份认证错误')
  }
  console.log(err)
  res.cc('未知错误')
})

// 启动服务器
app.listen(5500, () => {
  console.log('服务器运行在：http://127.0.0.1:5500')
})
